package com.fc.push.handler.pub;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.servlet.http.HttpServletResponse;

import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fc.commons.IDGenerator;
import com.fc.persistence.cache.ConstKey;
//import com.fc.persistence.cache.redis.redisServiceUtil;
import com.fc.persistence.dao.DAOTemplate;
import com.fc.push.GlobalServerConst;
import com.fc.push.db.TranscationFacade;
import com.fc.push.db.entities.Application;
import com.fc.push.db.entities.IMessage;
import com.fc.push.exception.MServerException;
import com.fc.push.handler.AbstractHttpHandler;
import com.fc.push.handler.HandlerResult;
import com.fc.push.handler.pub.service.APNsPublishUtil;
import com.fc.push.handler.pub.service.GlobalService;
import com.fc.push.handler.pub.service.MqttPublishUtil;
import com.fc.push.handler.pub.service.RedisServiceUtil;
import com.fc.push.handler.pub.service.WebPublishService;
import com.fc.remoting.anno.Protocol;
import com.fc.remoting.core.HttpProtocolTask;
import com.fc.remoting.logger.LogSystem;

import javapns.notification.PushNotificationPayload;

@Component
@Protocol(module = PublishConst.PUBLISH_MODULE_ID, order = PublishConst.ORDER_1)
public class PublishMsgHandler extends AbstractHttpHandler {
	
	private static final String APPKEY = "appkey";
	private static final String PLATFORM = "platform";
	private static final String MESSAGE = "message";
	private static final String TAG = "tag";
	private static final String AUDIENCE = "audience";
	private static final String REGISTRATION_ID = "registration_id";
	private static final String IS_ALL_FLAG = "isall";

	private static final String CODE = "code";

	
	@Autowired
	APNsPublishUtil apnsPublishUti;
	
	@Autowired
	MqttPublishUtil mqttPublishUtil;
	
	@Autowired 
	RedisServiceUtil redisServiceUtil;
	
	@Autowired 
	GlobalService globalService;
	
	@Override
	public Object handle(HttpServletResponse response, JSONObject request) {
		
		String platform = request.getString(PLATFORM);
		JSONObject audience = request.getJSONObject(AUDIENCE);
		JSONObject message = request.getJSONObject(MESSAGE);
		String appkey = request.getString(APPKEY);
		if (platform == null || platform.isEmpty()) {
			JSONObject object = HandlerResult.result();
			object.put(CODE, MessageRCode.RCODE_ERROR_1002);
			return object;
		}
		
		platform = platform.toLowerCase();

		String sql_app = "from " + Application.class.getSimpleName() + " where appkey = '" + appkey + "'";
		List<DAOTemplate> applist = TranscationFacade.getInstance().transcation().getBySQL(sql_app);
		if (applist == null || applist.size() == 0) {
			JSONObject object = HandlerResult.result();
			object.put(CODE, MessageRCode.RCODE_ERROR_1008);
			return object;
		}
		Application application = (Application) applist.get(0);
		if (!application.getPlatform().equals(platform)) {
			JSONObject object = HandlerResult.result();
			object.put(CODE, MessageRCode.RCODE_ERROR_1004);
			return object;
		}
		platform = application.getPlatform();
		// 保存发送的消息
		IMessage iMessage = new IMessage();
		iMessage.setId(IDGenerator.INSTANCE.generateId());
		iMessage.setMsg(message.toJSONString());
		iMessage.setAppkey(application.getAppkey());
		iMessage.setCreatedate(new Date());
		
		// 保存消息的条数
		String countkey = GlobalServerConst.APP_MESSAGE_COUNT.replaceFirst("APP", appkey);
		if (redisServiceUtil.existsProxy(countkey)) {
			redisServiceUtil.incrProxy(countkey);
		} else {
			redisServiceUtil.incrProxy(countkey);
			redisServiceUtil.incrProxy(countkey);
		}
		
		// 开始发送消息的逻辑
		if (audience != null) {
			String isAllFlag = audience.getString(IS_ALL_FLAG);
			JSONArray tag = null;
			JSONArray id = null;
			if (isAllFlag != null && isAllFlag.equals(GlobalServerConst.ALL)) {
				/**
				 * 推送给所有人
				 */
				if (platform.toLowerCase().equals(GlobalServerConst.ANDROID)) {

					MqttMessage payload = null;
					try {
						payload = mqttPublishUtil.assMqttPayload(message);
					} catch (UnsupportedEncodingException e) {
						globalService.setRCodeAndSave(iMessage, MessageRCode.RCODE_ERROR_1000);
						throw new MServerException(e, e.getMessage());
					}
					mqttPublishUtil.sendByTag(payload, "MESSAGE");

				} else if (platform.toLowerCase().equals(GlobalServerConst.IOS)) {
					String key = globalService.assKeyByAppkeyAndTag(appkey, ConstKey.IOS_APP_TAG_SET_TOKENS, "MESSAGE");
					Set<String> tokens = redisServiceUtil.smembersProxy(key);
					if (tokens == null || tokens.size() == 0) {
						JSONObject object = HandlerResult.result();
						object.put(CODE, MessageRCode.RCODE_ERROR_1011);
						return object;
					}

					PushNotificationPayload payload = null;
					try {
						payload = apnsPublishUti.assIOSPayload(message);
					} catch (org.json.JSONException e) {
						globalService.setRCodeAndSave(iMessage, MessageRCode.RCODE_ERROR_1000);
						throw new MServerException(e, e.getMessage());
					}

					// 是否是生产环境
					boolean isProduction = false;
					if (application.getIsproduction() == 1) {
						isProduction = true;
					}
					apnsPublishUti.pubMessageBySlice(application.getFile(), application.getPwd(),
							tokens, payload, isProduction);

				} else if (platform.toLowerCase().equals(GlobalServerConst.WEB)) {
					String key = globalService.assKeyByAppkeyAndTag(appkey, ConstKey.WEB_APP_TAG_SET_IDS, "MESSAGE");
					Set<String> res = redisServiceUtil.smembersProxy(key);
					if (res == null || res.size() == 0) {
						JSONObject object = HandlerResult.result();
						object.put(CODE, MessageRCode.RCODE_ERROR_1011);
						return object;
					}

					WebPublishService.getInstance().pubMessageBySlice(res, message);
				}
			} else if ((tag = audience.getJSONArray(TAG)) != null && tag.size() > 0) {
				/**
				 * 通过主题来推送
				 */
				Object[] tags = tag.toArray();
				if (tags.length > 0) {
					if (platform.toLowerCase().equals(GlobalServerConst.ANDROID)) {
						MqttMessage payload = null;
						try {
							payload = mqttPublishUtil.assMqttPayload(message);
						} catch (UnsupportedEncodingException e) {
							globalService.setRCodeAndSave(iMessage, MessageRCode.RCODE_ERROR_1000);
							throw new MServerException(e, e.getMessage());
						}
						if (!mqttPublishUtil.sendByTag(payload, tags)) {
							JSONObject object = HandlerResult.result();
							object.put(CODE, MessageRCode.RCODE_ERROR_1000);
							globalService.setRCodeAndSave(iMessage, MessageRCode.RCODE_ERROR_1000);
							return object;
						}
					} else if (platform.toLowerCase().equals(GlobalServerConst.IOS)) {
						Set<String> tokens = new HashSet<String>();
						for (Object t : tags) {
							String key = globalService.assKeyByAppkeyAndTag(appkey, ConstKey.IOS_APP_TAG_SET_TOKENS, t);
							Set<String> res = redisServiceUtil.smembersProxy(key);
							tokens.addAll(res);
						}

						PushNotificationPayload payload = null;
						try {
							payload = apnsPublishUti.assIOSPayload(message);
						} catch (org.json.JSONException e) {
							globalService.setRCodeAndSave(iMessage, MessageRCode.RCODE_ERROR_1000);
							throw new MServerException(e, e.getMessage());
						}

						// 是否是生产环境
						boolean isProduction = false;
						if (application.getIsproduction() == 1) {
							isProduction = true;
						}
						apnsPublishUti.pubMessageBySlice(application.getFile(), application.getPwd(),
								tokens, payload, isProduction);
					} else if (platform.toLowerCase().equals(GlobalServerConst.WEB)) {
						Set<String> ids = new HashSet<String>();
						for (Object t : tags) {
							String key = globalService.assKeyByAppkeyAndTag(appkey, ConstKey.WEB_APP_TAG_SET_IDS, t);
							Set<String> res = redisServiceUtil.smembersProxy(key);
							ids.addAll(res);
						}
						WebPublishService.getInstance().pubMessageBySlice(ids, message);
					}
				}
			} else if ((id = audience.getJSONArray(REGISTRATION_ID)) != null) {
				/**
				 * 通过id来推送
				 */
				Object[] ids = id.toArray();
				if (ids.length > 0) {
					if (platform.toLowerCase().equals(GlobalServerConst.ANDROID)) {
						MqttMessage payload = null;
						try {
							payload = mqttPublishUtil.assMqttPayload(message);
						} catch (UnsupportedEncodingException e) {
							globalService.setRCodeAndSave(iMessage, MessageRCode.RCODE_ERROR_1000);
							throw new MServerException(e, e.getMessage());
						}

						// 过滤掉未注册的设备
						List<Object> idList = new ArrayList<Object>();
						Collections.addAll(idList, ids);
						globalService.filterUnregisteredIDWhenPushedByID(idList, appkey);
						// 推送
						mqttPublishUtil.pubMessageBySlice(appkey, payload, idList.toArray());
					} else if (platform.toLowerCase().equals(GlobalServerConst.IOS)) {
						// 根据TOKEN数组推送IOS消息
						
						// 过滤掉未注册的设备
						List<Object> idList = new ArrayList<Object>();
						Collections.addAll(idList, ids);
						List<Object> result = globalService.filterUnregisteredIDWhenPushedByID(idList, appkey);
						
						if(idList.size() > 0){
							//Mqtt推送
							MqttMessage mqttPayload = null;
							try {
								mqttPayload = mqttPublishUtil.assMqttPayload(message);
							} catch (UnsupportedEncodingException e) {
								globalService.setRCodeAndSave(iMessage, MessageRCode.RCODE_ERROR_1000);
								throw new MServerException(e, e.getMessage());
							}
							mqttPublishUtil.pubMessageBySlice(appkey, mqttPayload, idList.toArray());
						}
						
						if(result.size() > 0){
							// APNs推送
							PushNotificationPayload apnsPayload = null;
							try {
								apnsPayload = apnsPublishUti.assIOSPayload(message);
							} catch (org.json.JSONException e) {
								globalService.setRCodeAndSave(iMessage, MessageRCode.RCODE_ERROR_1000);
								throw new MServerException(e, e.getMessage());
							}
							// 是否是生产环境
							boolean isProduction = false;
							if (application.getIsproduction() == 1) {
								isProduction = true;
							}
							
							apnsPublishUti.pubMessageBySlice(application.getFile(), application.getPwd(),
									apnsPayload, isProduction, result.toArray());
						}
					} else if (platform.toLowerCase().equals(GlobalServerConst.WEB)) {
						List<Object> idList = new ArrayList<Object>();
						Collections.addAll(idList, ids);
						// 过滤掉未注册的设备
						globalService.filterUnregisteredIDWhenPushedByID(idList, appkey);
						// 推送
						WebPublishService.getInstance().pubMessageBySlice(idList.toArray(), message);
					}
				}
			}
		}

		globalService.setRCodeAndSave(iMessage, MessageRCode.RCODE_SUCCESS);
		return HandlerResult.result();
	}
}
